(:import module namespace functx = "http://www.functx.com" at "http://www.xqueryfunctions.com/xq/functx-1.0-nodoc-2007-01.xq";:)

declare namespace javaXMLModule="java:io.FileWrite";
declare namespace uuid="java:java.util.UUID";

declare function local:normalizeComposer($composers as element(Composers)?) as xs:string
{ let $composersList := doc("../Aufgabe2/KomponistenUUID.xml")/Composers
    let $result :=
    for $a in $composers/Assignments
        return if(count($a/ComposerUUID) > 1) then 
                   $a/@groupCompound 
               else (
                   let $foundComposer := $composersList/Composer[ComposerUUID = $a/ComposerUUID]
                   return (concat($foundComposer/Surname, ",", $foundComposer/Forename))
               )
    return string-join($result,";") };

declare function local:cleanAlbum($album as xs:string?)
{
    if (fn:exists($album)) then (
        let $normc := fn:normalize-space($album),
            $validname := "[a-z|A-Z|ü|ä|ö|Ü|Ä|Ö|ß|é|\-|ó|ř|á]+",
            (:Surname: ...:)
            $reg1 := fn:concat("^", $validname, ":.*$"),        
            (:Initialen. Initialen. Surname - ... (Disc 2):)
            $reg2 := fn:concat("^", $validname, "\.\s", $validname, "\.\s", $validname, "\s-\s.*\(", $validname, "\s\d{1}\)$"),
            (:Surname (Initialen Initialen): ... [Disc 2]:)
            $reg3 := fn:concat("^", $validname, "\s\(", $validname, "\):.*\[", $validname, "\s.*$"),            
            (:Surname; Surname: ...:)
            $reg4 := fn:concat("^", $validname, ";\s", $validname, ":.*$"),                
            (:Initialen.Initialen.Surname / ...:)
            $reg7 := fn:concat("^", $validname, "\.", $validname, "\.", $validname, "\s/\s"),
            (:Isaac Stern - A Life In Music - Beethoven - Brahms: Violin Concertos - Triple Concerto - Double Concerto:)
            $reg8 := fn:concat("^.*\s\-\s.*\s\-\s", $validname ,"\s\-\s", $validname,":\s.*\s\-\s.*\s\-\s.*$")
        return
            if (fn:matches($normc, $reg1) or fn:matches($normc, $reg4) or fn:matches($normc, $reg3))
                (:Surname: ...:)            
                then fn:substring-after($normc,": ")
            else if (fn:matches($normc, $reg2))
                (:Initialen. Initialen. Surname - ... (Disc 2):)                       
                then fn:substring-after($normc,"- ")
            else if (fn:matches($normc, $reg7))
                 (:Initialen.Initialen.Surname / ...:)
                 then fn:substring-after($normc,"/ ")
            else if (fn:matches($normc, $reg8))
                 (:Isaac Stern - A Life In Music - Beethoven - Brahms: Violin Concertos - Triple Concerto - Double Concerto:)            
                 then fn:substring-before(fn:substring-after($normc,"- "), " -")
            else ($normc)
        ) else ()
};

declare function local:cleanName($name as xs:string?)
{
    if (fn:exists($name)) then (
        let $normc := fn:normalize-space($name),
            $validname := "[a-z|A-Z|ü|ä|ö|Ü|Ä|Ö|ß|é|\-|ó|ř|á]+",
            (:Surname I* Surname:)
            $reg1 := fn:concat("^", $validname, "\sI[I | &amp; | \s]*\s", $validname, "$"),        
            (:Surname: ...:)
            $reg2 := fn:concat("^", $validname, ":\s"),
            (:Saint-Saens Sonate 1 Satz 4 (Allegro molto)
              Debussy Sonate Satz 1 (Allegro vivo):)
            $reg4 := fn:concat("^", $validname, "\s", $validname, "\s\d?\s?", $validname, "\s\d\s\(.*\)$"),
            (:Bach Partita 3: Preludio (Martzy):)
            $reg5 := fn:concat("^", $validname, "\s", $validname, "\s\d:\s"),
            (:Concerto according to Pinchas 1 (Bruch)
              Concerto according to Pinchas (Brahms):)
            $reg6 := fn:concat("^", $validname, "\s", $validname, "\s", $validname, "\s", $validname, "\s\d?\s?\(.*\)"),
            (:Tchaikovsky Violinkonzert I Allegro moderato (Ormandy, Stern):)
            $reg7 := fn:concat("^", $validname, "\s", $validname, "\sI+.*\(.*\)$"),
            (:Michael, Haydn: ...:)
            $reg8 := fn:concat("^", $validname, ",\s", $validname, ":"),
            (:J. S. Bach / Partita for solo Vn 2 d-moll BWV 1004 1. Allemande:)
            $reg9 := fn:concat("^", $validname, "\.\s?", $validname, "\.\s?", $validname, "\s/.*"),
            (:Bach: Violin Partita #2 In D Minor, BWV 1004 - 1. Allemanda:)
            $reg10 := fn:concat("^", $validname, ":\s", $validname, "\s", $validname, "#\d\s"),
            (:J. S. Bach - Partita for solo Vn 2 d-moll BWV 1004 1. Allemande:)
            $reg11 := fn:concat("^", $validname, "\.\s?", $validname, "?\.?\s?", $validname, "\s-.*"),
            (:LeClair - Sonata No 3-1 in D Major Andante -Szeryng:)
            $reg12 := fn:concat("^", $validname, "\s-\s"),
            (:Bach (JS): ...:)
            $reg13 := fn:concat("^", $validname, "\s\(", $validname, "\):\s"),
            (:Brandl/Kreisler: ...:)
            $reg14 := fn:concat("^", $validname, "/", $validname, ":\s") 
        return
            (:Surname I* Surname or Surname:)
            if (fn:matches($normc, $reg1) or fn:matches($normc, $reg4) or fn:matches($normc, $reg5) or
                fn:matches($normc, $reg7) or fn:matches($normc, $reg10)) then (
                fn:normalize-space(fn:substring-after($normc, " "))
            )
            (:Surname: ... (.*) or Surname, Forename: ... (...) or Surname (Initialen): ...:)
            else if (fn:matches($normc, $reg2) or fn:matches($normc, $reg8) or fn:matches($normc, $reg13) or
                     fn:matches($normc, $reg14)) then (
                fn:normalize-space(fn:substring-after($normc, ":"))
            )
            else if (fn:matches($normc, $reg6)) then
                fn:normalize-space(fn:substring-before($normc, "("))
            else if (fn:matches($normc, $reg9)) then
                fn:normalize-space(fn:substring-after($normc, "/"))
            else if (fn:matches($normc, $reg11) or fn:matches($normc, $reg12)) then
                fn:normalize-space(fn:substring-after($normc, " -"))       
            else ($normc)
        ) else ()
};

for $mediathek in doc("../Aufgabe3/Aufgabe3_output.xml")/Mediathek
return <Mediathek>{
    ($mediathek/MetaData)
    union
    (javaXMLModule:init(substring-after(concat(substring-before(fn:static-base-uri(),"Aufgabe4.xquery"),"Aufgabe4_history.xml"),"file:")),
    javaXMLModule:println("<History>"),    
    for $trackarea in $mediathek/TrackArea
    return <TrackArea>{
    (:java Ausgabe :)
        for $track in $trackarea/Track
        let $cleanedAlbum := local:cleanAlbum($track/Album/text()),
            $cleanedName := local:cleanName($track/Name/text())
        return <Track> {
            $track/*[name()!= "Album" and name() != "Composer" and name() != "Name"]
            union
            (if (fn:not($track/Album) or $track/Album/text() = $cleanedAlbum) then 
                $track/Album
            else (
                let $uuid := uuid:randomUUID()
                return (javaXMLModule:println(fn:concat("<Album uuid='", $uuid, "' timestamp='", fn:current-dateTime(),
                                                (:"' cleanedAlbum='", $cleanedAlbum,:) "'>", $track/Album/text(), "</Album>")),
                <Album uuid="{$uuid}" timestamp="{fn:current-dateTime()}"> {$cleanedAlbum} </Album>)
            ))
            union
            (if (fn:not($track/Name) or $track/Name/text() = $cleanedName) then
                $track/Name
            else (
                let $uuid := uuid:randomUUID()
                return (javaXMLModule:println(fn:concat("<Name uuid='", $uuid, "' timestamp='", fn:current-dateTime(),
                                                (:"' cleanedName='", $cleanedName,:) "'>", $track/Name/text(), "</Name>")),
                <Name uuid="{$uuid}" timestamp="{fn:current-dateTime()}"> {$cleanedName} </Name>)                
            ))        
            union
            (let $normalizedComposer := local:normalizeComposer($track/Composers)
            return
                if (fn:not($track/Composer) and fn:not($track/Composers)) 
                    then ()
                else (if (fn:not($track/Composers) or $track/Composer/text() = $normalizedComposer) 
                    then ($track/Composer)
                else (if(fn:not($track/Composer)) 
                    then (
                    let $uuid := uuid:randomUUID()
                    return (javaXMLModule:println(fn:concat("<Composer uuid='", $uuid, "' timestamp='", fn:current-dateTime(), (:"' cleanedComp='", $normalizedComposer,:)
                                                    "'/>")),
                    <Composer uuid="{$uuid}" timestamp="{fn:current-dateTime()}"> {$normalizedComposer} </Composer>) 
                    )
                else (
                    let $uuid := uuid:randomUUID()
                    return (javaXMLModule:println(fn:concat("<Composer uuid='", $uuid, "' timestamp='", fn:current-dateTime(), (:"' cleanedComp='", $normalizedComposer,:)
                                                    "'>", $track/Composer/text(), "</Composer>")),
                    <Composer uuid="{$uuid}" timestamp="{fn:current-dateTime()}"> {$normalizedComposer} </Composer>)  
                )                    
            )))
        }</Track>
    }</TrackArea>,
    javaXMLModule:println("</History>"),
    javaXMLModule:close())
    union
    ($mediathek/Playlists)
}</Mediathek>